"""
存储引擎适配器 - 通过 DatabaseServerAdapter 获取底层存储引擎
将 DatabaseServerAdapter 的完整封装适配到 ExecutionEngine 期望的接口
"""

import os
from typing import List, Dict, Any, Iterator, Optional
from .types import TableInfo, IndexInfo, Record
from OperatingSystem.database_server_adapter import DatabaseServerAdapter
from OperatingSystem.storage_engine import StorageEngine, CachePolicy
from OperatingSystem.table_schema import TableSchema, Column, ColumnType


class StorageEngineAdapter:
    """存储引擎适配器 - 使用 DatabaseServerAdapter 的完整封装，支持用户认证"""
    
    def __init__(self, data_root: str = "./demo_database", database_name: str = "default", db_adapter=None):
        """
        初始化存储引擎适配器
        
        Args:
            data_root: 数据根目录
            database_name: 数据库名称
            db_adapter: 可选的已存在的DatabaseServerAdapter实例，避免创建多个服务器
        """
        # 使用已存在的adapter或创建新的
        if db_adapter is not None:
            self.db_adapter = db_adapter
            print(f"[StorageAdapter] 使用已存在的DatabaseServerAdapter实例")
        else:
            # 创建 DatabaseServerAdapter 实例
            self.db_adapter = DatabaseServerAdapter(
                data_root=data_root,
                cache_size=100,
                cache_policy=CachePolicy.LRU,
                enable_locking=True
            )
            print(f"[StorageAdapter] 创建新的DatabaseServerAdapter实例")
        
        # 用户认证状态
        self.is_authenticated = False
        self.current_user = None
        self.database_name = database_name
        self.session_id = None
        
        # 不再自动连接，需要先认证
        self.os_storage = None
        print(f"[StorageAdapter] 使用DatabaseServerAdapter管理数据库操作，需要用户认证")
    
    def login(self, username: str, password: str) -> bool:
        """
        用户登录
        
        Args:
            username: 用户名
            password: 密码
            
        Returns:
            bool: 登录是否成功
        """
        try:
            print(f"[StorageAdapter] 尝试登录用户: {username}")
            
            # 使用数据库服务器适配器进行用户认证
            success = self.db_adapter.login(username, password)
            
            if success:
                self.is_authenticated = True
                self.current_user = username
                self.session_id = self.db_adapter.session_id
                print(f"[StorageAdapter] 用户 {username} 登录成功")
                
                # 登录成功后，尝试切换到指定数据库
                if self.database_name and self.database_name != "default":
                    self.use_database(self.database_name)
                else:
                    # 尝试获取当前数据库的存储引擎实例
                    self._update_current_database_storage()
                
                return True
            else:
                print(f"[StorageAdapter] 用户 {username} 登录失败")
                return False
                
        except Exception as e:
            print(f"[StorageAdapter] 登录异常: {e}")
            return False
    
    def logout(self):
        """用户注销"""
        try:
            if self.is_authenticated:
                print(f"[StorageAdapter] 用户 {self.current_user} 注销")
                self.db_adapter.logout()
            
            self._reset_auth_state()
            
        except Exception as e:
            print(f"[StorageAdapter] 注销异常: {e}")
            self._reset_auth_state()
    
    def _reset_auth_state(self):
        """重置认证状态"""
        self.is_authenticated = False
        self.current_user = None
        self.session_id = None
        self.os_storage = None
    
    def get_current_user(self) -> Optional[str]:
        """获取当前用户"""
        return self.current_user if self.is_authenticated else None
    
    def is_user_authenticated(self) -> bool:
        """检查用户是否已认证"""
        return self.is_authenticated
    
    def use_database(self, database_name: str) -> bool:
        """
        切换数据库
        
        Args:
            database_name: 数据库名称
            
        Returns:
            bool: 切换是否成功
        """
        if not self.is_authenticated:
            print("[StorageAdapter] 用户未认证，无法切换数据库")
            return False
        
        try:
            success = self.db_adapter.use_database(database_name)
            if success:
                self.database_name = database_name
                self._update_current_database_storage()
                print(f"[StorageAdapter] 成功切换到数据库: {database_name}")
                return True
            else:
                print(f"[StorageAdapter] 切换数据库失败: {database_name}")
                return False
        except Exception as e:
            print(f"[StorageAdapter] 切换数据库异常: {e}")
            return False
    
    def get_accessible_databases(self) -> List[str]:
        """获取用户可访问的数据库列表"""
        if not self.is_authenticated:
            return []
        
        try:
            return self.db_adapter.get_accessible_databases()
        except Exception as e:
            print(f"[StorageAdapter] 获取可访问数据库列表失败: {e}")
            return []
    
    def _check_authentication(self) -> bool:
        """检查认证状态，用于所有数据库操作前的验证"""
        if not self.is_authenticated:
            print("[StorageAdapter] 操作被拒绝：用户未认证")
            return False
        return True
    
    def _get_underlying_storage_engine(self) -> StorageEngine:
        """获取底层存储引擎实例"""
        # 从 DatabaseServerAdapter 的内部结构获取存储引擎
        database_server = self.db_adapter.database_server
        database_manager = database_server.database_manager
        
        # 确保数据库存在
        if self.database_name not in database_manager.databases:
            # 创建数据库
            database_manager.create_database(self.database_name)
        
        # 获取数据库实例
        db_instance = database_manager.get_database(self.database_name)
        if db_instance:
            # 切换当前数据库上下文
            self.db_adapter.use_database(self.database_name)
            return db_instance.storage_engine
        else:
            raise RuntimeError(f"Failed to get database instance: {self.database_name}")
    
    def _update_current_database_storage(self):
        """更新当前数据库的存储引擎实例"""
        try:
            self.os_storage = self._get_underlying_storage_engine()
            print(f"[StorageAdapter] 已更新到数据库 {self.database_name} 的存储引擎")
        except Exception as e:
            print(f"[StorageAdapter] 更新存储引擎失败: {e}")
            self.os_storage = None
    
    def get_current_database_tables(self) -> List[str]:
        """获取当前数据库的表列表"""
        if not self._check_authentication():
            return []
            
        try:
            # 确保存储引擎实例是最新的
            if self.os_storage is None:
                self._update_current_database_storage()
            
            if self.os_storage:
                tables = self.os_storage.get_table_list()
                print(f"[StorageAdapter] 获取到 {len(tables)} 个表: {tables}")
                return tables
            else:
                print("[StorageAdapter] 存储引擎实例为None，无法获取表列表")
                return []
        except Exception as e:
            print(f"[StorageAdapter] 获取表列表失败: {e}")
            return []
    
    def scan_table(self, table_name: str, 
                   columns: Optional[List[str]] = None,
                   predicate: Optional[str] = None) -> Iterator[Record]:
        """扫描表数据"""
        if not self._check_authentication():
            return iter([])
            
        try:
            # 首先检查表是否存在
            if not self.os_storage.table_exists(table_name):
                print(f"[StorageAdapter] 表 {table_name} 不存在")
                return iter([])
            
            # 使用 OperatingSystem 的 select_records 方法
            records = self.os_storage.select_records(table_name)
            
            print(f"[StorageAdapter] 扫描表 {table_name}，找到 {len(records)} 条记录")
            
            # 过滤掉无效记录（避免垃圾数据）
            valid_records = []
            for record in records:
                if self._is_valid_record(record):
                    valid_records.append(record)
                else:
                    print(f"[StorageAdapter] 跳过无效记录: {record}")
            
            print(f"[StorageAdapter] 有效记录数: {len(valid_records)}")
            
            for record in valid_records:
                # 应用列过滤
                if columns and '*' not in columns:
                    filtered_record = {col: record.get(col) for col in columns if col in record}
                else:
                    filtered_record = record
                
                # 简单的谓词过滤（这里可以扩展更复杂的逻辑）
                if predicate:
                    # 简化版本：只处理简单的数值比较
                    if self._simple_predicate_check(filtered_record, predicate):
                        yield filtered_record
                else:
                    yield filtered_record
                    
        except Exception as e:
            print(f"[StorageAdapter] 扫描表失败: {e}")
            import traceback
            traceback.print_exc()
            # 如果出错，返回空迭代器
            return iter([])
    
    def _is_valid_record(self, record: Record) -> bool:
        """检查记录是否有效（过滤垃圾数据）"""
        if not record or not isinstance(record, dict):
            return False
        
        # 检查是否有有效的值
        has_valid_value = False
        for key, value in record.items():
            if value is not None and value != '' and value != 0:
                has_valid_value = True
                break
        
        # 如果所有值都是空/0，且记录包含可疑的大数字，可能是垃圾数据
        if not has_valid_value:
            for key, value in record.items():
                if isinstance(value, int) and value > 1000000:  # 可疑的大整数
                    return False
        
        return True
    
    def _parse_predicate(self, predicate: str) -> Optional[Dict]:
        """将字符串谓词转换为字典条件"""
        try:
            # 解析简单的比较操作，如 "amount > 200"
            if '>' in predicate:
                parts = predicate.split('>')
                if len(parts) == 2:
                    field = parts[0].strip()
                    value = parts[1].strip()
                    try:
                        return {field: {"$gt": float(value)}}
                    except:
                        return {field: {"$gt": value.strip("'\"")}}
            elif '<' in predicate:
                parts = predicate.split('<')
                if len(parts) == 2:
                    field = parts[0].strip()
                    value = parts[1].strip()
                    try:
                        return {field: {"$lt": float(value)}}
                    except:
                        return {field: {"$lt": value.strip("'\"")}}
            elif '=' in predicate:
                parts = predicate.split('=')
                if len(parts) == 2:
                    field = parts[0].strip()
                    value = parts[1].strip()
                    return {field: value.strip("'\"")}
            
            # 默认返回 None（无条件）
            return None
        except:
            return None
    
    def _simple_predicate_check(self, record: Record, predicate: str) -> bool:
        """简单的谓词检查"""
        try:
            # 解析简单的比较操作，如 "amount > 200"
            if '>' in predicate:
                parts = predicate.split('>')
                if len(parts) == 2:
                    field = parts[0].strip()
                    value = parts[1].strip()
                    if field in record:
                        try:
                            return float(record[field]) > float(value)
                        except:
                            return str(record[field]) > value
            elif '<' in predicate:
                parts = predicate.split('<')
                if len(parts) == 2:
                    field = parts[0].strip()
                    value = parts[1].strip()
                    if field in record:
                        try:
                            return float(record[field]) < float(value)
                        except:
                            return str(record[field]) < value
            elif '=' in predicate:
                parts = predicate.split('=')
                if len(parts) == 2:
                    field = parts[0].strip()
                    value = parts[1].strip()
                    if field in record:
                        return str(record[field]) == value.strip("'\"")
            
            # 默认返回 True（不过滤）
            return True
        except:
            return True
    
    def get_table_info(self, table_name: str) -> TableInfo:
        """获取表信息"""
        if not self._check_authentication():
            return TableInfo(name=table_name, columns=[])
            
        try:
            schema = self.os_storage.get_table_schema(table_name)
            if schema:
                # 转换为 TableInfo
                # 获取列信息
                column_infos = []
                for col in schema.columns:
                    from .types import ColumnInfo, DataType
                    # 转换列类型
                    if col.type.value == 'INT':
                        data_type = DataType.INTEGER
                    elif col.type.value == 'VARCHAR':
                        data_type = DataType.VARCHAR
                    elif col.type.value == 'FLOAT':
                        data_type = DataType.FLOAT
                    else:
                        data_type = DataType.VARCHAR
                    
                    column_info = ColumnInfo(
                        name=col.name,
                        data_type=data_type,
                        nullable=col.nullable
                    )
                    column_infos.append(column_info)
                
                return TableInfo(
                    name=schema.table_name,
                    columns=column_infos
                )
            else:
                # 返回默认表信息
                return TableInfo(
                    name=table_name,
                    columns=[]
                )
        except:
            return TableInfo(
                name=table_name,
                columns=[]
            )
    
    def get_index_info(self, table_name: str) -> List[IndexInfo]:
        """获取索引信息"""
        # OperatingSystem 暂时不支持索引，返回空列表
        return []
    
    def create_table(self, table_name: str, columns) -> bool:
        """创建表"""
        if not self._check_authentication():
            return False
            
        try:
            # 如果os_storage为None，尝试重新获取
            if self.os_storage is None:
                print(f"[StorageAdapter] os_storage为None，尝试重新获取")
                self._update_current_database_storage()
                
            if self.os_storage is None:
                print(f"[StorageAdapter] 无法获取存储引擎，创建表失败")
                return False
            
            # 首先检查表是否已经存在
            if self.os_storage.table_exists(table_name):
                print(f"[StorageAdapter] 表 {table_name} 已经存在")
                return False
            
            # 转换列定义格式
            os_columns = []
            for col in columns:
                if isinstance(col, dict):
                    # 从字典格式转换
                    col_name = col.get('name')
                    col_type = col.get('type', 'VARCHAR')
                    
                    # 转换类型
                    if col_type.upper() in ['INT', 'INTEGER']:
                        os_col_type = ColumnType.INT
                        os_column = Column(col_name, os_col_type)
                    elif col_type.upper() in ['VARCHAR', 'STRING', 'TEXT']:
                        os_col_type = ColumnType.VARCHAR
                        # VARCHAR类型需要长度，默认设置为255
                        os_column = Column(col_name, os_col_type, length=255)
                    elif col_type.upper() in ['FLOAT', 'DOUBLE']:
                        os_col_type = ColumnType.FLOAT
                        os_column = Column(col_name, os_col_type)
                    else:
                        # 默认VARCHAR类型，长度255
                        os_col_type = ColumnType.VARCHAR
                        os_column = Column(col_name, os_col_type, length=255)
                    
                    os_columns.append(os_column)
                else:
                    # 假设已经是Column对象
                    os_columns.append(col)
            
            print(f"[StorageAdapter] 创建表 {table_name}，列: {[c.name for c in os_columns]}")
            result = self.os_storage.create_table(table_name, os_columns)
            print(f"[StorageAdapter] 创建表结果: {result}")
            
            # 如果创建成功，立即保存到磁盘并同步元数据
            if result:
                print(f"[StorageAdapter] 立即保存表结构到磁盘")
                self.os_storage._save_table_schemas()
                self.os_storage._save_table_mappings()
                self.os_storage.flush_all_pages()
                
                # 重要：强制重新加载表元数据到内存中，确保后续操作能找到新创建的表
                print(f"[StorageAdapter] 重新加载表元数据以同步内存状态")
                self.os_storage._load_table_schemas()
                self.os_storage._load_table_mappings()
            
            return result
        except Exception as e:
            print(f"[StorageAdapter] 创建表失败: {e}")
            import traceback
            traceback.print_exc()
            return False
    
    def drop_table(self, table_name: str) -> bool:
        """删除表"""
        if not self._check_authentication():
            return False
            
        return self.os_storage.drop_table(table_name)
    
    def insert_record(self, table_name: str, record: Record) -> bool:
        """插入记录"""
        if not self._check_authentication():
            return False
            
        try:
            print(f"[StorageAdapter] 插入记录到表 {table_name}: {record}")
            result = self.os_storage.insert_record(table_name, record)
            print(f"[StorageAdapter] 插入记录结果: {result}")
            
            # 如果插入成功，立即刷新缓存确保数据持久化
            if result:
                print(f"[StorageAdapter] 立即刷新缓存确保数据持久化")
                self.os_storage.flush_all_pages()
            
            return result
        except Exception as e:
            print(f"[StorageAdapter] 插入记录失败: {e}")
            import traceback
            traceback.print_exc()
            return False
    
    def update_records(self, table_name: str, condition: Dict[str, Any], updates: Dict[str, Any]) -> int:
        """更新记录"""
        if not self._check_authentication():
            return 0
            
        try:
            print(f"[StorageAdapter] 更新表 {table_name} 中的记录")
            print(f"[StorageAdapter] 条件: {condition}")
            print(f"[StorageAdapter] 更新内容: {updates}")
            
            result = self.os_storage.update_records(table_name, condition, updates)
            print(f"[StorageAdapter] 更新结果: {result} 条记录")
            
            # 如果更新成功，立即刷新缓存确保数据持久化
            if result > 0:
                print(f"[StorageAdapter] 立即刷新缓存确保更新持久化")
                self.os_storage.flush_all_pages()
            
            return result
        except Exception as e:
            print(f"[StorageAdapter] 更新记录失败: {e}")
            return 0

    def delete_records(self, table_name: str, condition: Dict[str, Any]) -> int:
        """删除记录"""
        if not self._check_authentication():
            return 0
            
        try:
            print(f"[StorageAdapter] 删除表 {table_name} 中的记录")
            print(f"[StorageAdapter] 条件: {condition}")
            
            result = self.os_storage.delete_records(table_name, condition)
            print(f"[StorageAdapter] 删除结果: {result} 条记录")
            
            # 如果删除成功，立即刷新缓存确保数据持久化
            if result > 0:
                print(f"[StorageAdapter] 立即刷新缓存确保删除持久化")
                self.os_storage.flush_all_pages()
            
            return result
        except Exception as e:
            print(f"[StorageAdapter] 删除记录失败: {e}")
            return 0
    
    def grant_privilege(self, username: str, host: str, privilege: str, 
                       database: str = None, table: str = None) -> bool:
        """
        授予权限
        
        Args:
            username: 用户名
            host: 主机
            privilege: 权限类型 (SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALL_PRIVILEGES等)
            database: 数据库名（可选）
            table: 表名（可选）
            
        Returns:
            bool: 授权成功返回True
        """
        if not self._check_authentication():
            print(f"[StorageAdapter] 用户未认证，无法执行GRANT操作")
            return False
        
        try:
            # 调用DatabaseServerAdapter的grant_privilege方法
            result = self.db_adapter.grant_privilege(username, host, privilege, database, table)
            
            if result:
                print(f"[StorageAdapter] 成功向用户 '{username}@{host}' 授予 '{privilege}' 权限")
                if database and table:
                    print(f"[StorageAdapter] 权限作用于表: {database}.{table}")
                elif database:
                    print(f"[StorageAdapter] 权限作用于数据库: {database}")
                else:
                    print(f"[StorageAdapter] 全局权限")
            else:
                print(f"[StorageAdapter] 向用户 '{username}@{host}' 授予 '{privilege}' 权限失败")
            
            return result
            
        except Exception as e:
            print(f"[StorageAdapter] 权限授予异常: {e}")
            return False
    
    def revoke_privilege(self, username: str, host: str, privilege: str,
                        database: str = None, table: str = None) -> bool:
        """
        撤销权限
        
        Args:
            username: 用户名
            host: 主机
            privilege: 权限类型
            database: 数据库名（可选）
            table: 表名（可选）
            
        Returns:
            bool: 撤销成功返回True
        """
        if not self._check_authentication():
            print(f"[StorageAdapter] 用户未认证，无法执行REVOKE操作")
            return False
        
        try:
            # 调用DatabaseServerAdapter的revoke_privilege方法
            result = self.db_adapter.revoke_privilege(username, host, privilege, database, table)
            
            if result:
                print(f"[StorageAdapter] 成功从用户 '{username}@{host}' 撤销 '{privilege}' 权限")
                if database and table:
                    print(f"[StorageAdapter] 权限作用于表: {database}.{table}")
                elif database:
                    print(f"[StorageAdapter] 权限作用于数据库: {database}")
                else:
                    print(f"[StorageAdapter] 全局权限")
            else:
                print(f"[StorageAdapter] 从用户 '{username}@{host}' 撤销 '{privilege}' 权限失败")
            
            return result
            
        except Exception as e:
            print(f"[StorageAdapter] 权限撤销异常: {e}")
            return False

    def close(self):
        """关闭存储引擎"""
        try:
            if hasattr(self.os_storage, 'close'):
                self.os_storage.close()
            if hasattr(self.db_adapter, 'close'):
                self.db_adapter.close()
        except Exception as e:
            print(f"[StorageAdapter] 关闭适配器失败: {e}")
